<template>
  <div ref="chartDom" />
</template>

<script lang="ts">
import { defineComponent, inject, onMounted, onUnmounted, ref, watch } from 'vue';
import echarts, { ECharts } from 'echarts';
import { debounce } from 'lodash-es';
import { addListener, removeListener } from 'resize-detector';
import dark from './dark';

echarts.registerTheme('dark-pro', dark);

export default defineComponent({
  emits: ['echart:click', 'zrender:click', 'selected:click', 'echartLeave'],
  props: {
    option: {
      type: Object,
      default: () => {
        return {};
      },
    },
    currentTheme: {
      type: String,
      default: 'dark',
    },
  },
  setup(props, { emit }) {
    const chartDom = ref<HTMLDivElement | null>(null);
    let chart: ECharts | null = null;
    const isRealDark = inject('isRealDark', ref(false));
    const resizeChart = () => {
      chart?.resize();
    };
    const resize = debounce(resizeChart, 300);

    const disposeChart = () => {
      if (chartDom.value) {
        removeListener(chartDom.value, resize);
      }
      chart?.off('click');
      (chart as any)?.getZr()?.off('click');
      chart?.dispose(); // 销毁实例，实例销毁后无法再被使用。
      chart = null;
    };
    const initChart = () => {
      disposeChart();
      if (chartDom.value) {
        // init echarts
        const theme = isRealDark.value && props.currentTheme === 'dark' ? 'dark-pro' : undefined;
        chart = echarts.init(chartDom.value, theme);
        chart.setOption(props.option, true);
        chart.on('click', e => {
          emit('echart:click', e);
        });
        chart.on('globalout', e => {
          if (e.dataIndex != 0) {
            emit('echartLeave', true);
          }
        });
        chart.on('legendselectchanged', e => {
          emit('selected:click', e);
        });
        (chart as any).getZr().on('click', params => {
          emit('zrender:click', params);
        });
        addListener(chartDom.value, resize);
      }
    };

    const getChart = () => {
      return chart;
    };

    const getIndexByEvent = e => {
      const pointInPixel = [e.offsetX, e.offsetY];
      if (chart?.containPixel({ seriesIndex: 0 }, pointInPixel)) {
        const pointInGrid = chart?.convertFromPixel({ seriesIndex: 0 }, pointInPixel) || [];
        const index = pointInGrid[0]; //X轴序号
        return index;
      } else {
        return -1;
      }
    };
    const getIndexByEventY = e => {
      const pointInPixel = [e.offsetX, e.offsetY];
      if (chart?.containPixel({ seriesIndex: 0 }, pointInPixel)) {
        const pointInGrid = chart?.convertFromPixel({ seriesIndex: 0 }, pointInPixel) || [];
        const index = pointInGrid[1]; //Y轴序号
        return index;
      } else {
        return -1;
      }
    };
    watch(
      isRealDark,
      () => {
        initChart();
      },
      { flush: 'post' },
    );
    onMounted(() => {
      watch(
        () => props.option,
        () => {
          chart?.setOption(props.option);
        },
        { deep: true, flush: 'post' },
      );
      initChart();
    });

    onUnmounted(() => {
      disposeChart();
    });

    return {
      chartDom,
      getChart,
      getIndexByEvent,
      getIndexByEventY,
    };
  },
});
</script>
